﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.HVAC;
using YArchitech.LIB;
using YArchitech.Plumbing;
using YArchitech.Revit;
using HYCreateDuct.FormDuct;
using HYCreateDuct.MethodHelp;

namespace HYCreateDuct.MethodCreateDuct
{
	public class CreateJigLine
	{
		public bool CreateDuctLine(UIApplication uiApp, FormCreateDuct cdt)
		{
			List<Curve> list = new List<Curve>();
			List<Duct> list2 = new List<Duct>();
			Selection selection = uiApp.ActiveUIDocument.Selection;
			UIDocument activeUIDocument = uiApp.ActiveUIDocument;
			Document document = activeUIDocument.Document;
			Transaction transaction = null;
			bool result;
			for (;;)
			{
				try
				{
					if (cdt.blTiqvDuct)
					{
						cdt.blTiqvDuct = false;
						ISelectionFilter selectionFilter = new DuctFilter();
						Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "选择一根风管……");
						Duct duct = document.GetElement(reference) as Duct;
						if (duct != null)
						{
							DuctWindowStruct ductParameter = GetDuctPara.GetDuctParameter(uiApp.ActiveUIDocument.Document, duct);
							for (int i = 0; i < cdt.cbSystemType.Items.Count; i++)
							{
								if (cdt.cbSystemType.Items[i].Equals(ductParameter.strSystemType))
								{
									cdt.cbSystemType.SelectedIndex = i;
									break;
								}
							}
							for (int j = 0; j < cdt.cbDuctType.Items.Count; j++)
							{
								if (cdt.cbDuctType.Items[j].ToString().Contains(ductParameter.strDuctType) && ((cdt.cbDuctType.Items[j].ToString().Contains("椭圆") && ductParameter.strDuctType.Contains("椭圆")) || (!cdt.cbDuctType.Items[j].ToString().Contains("椭圆") && !ductParameter.strDuctType.Contains("椭圆"))))
								{
									cdt.cbDuctType.SelectedIndex = j;
									break;
								}
							}
							cdt.tbFlow.Text = ductParameter.dDuctFlow.ToString();
							if (ductParameter.dDuctDiameter == 0.0)
							{
								cdt.txtWidth.Text = ductParameter.dDuctWidth.ToString();
								cdt.txtHeight.Text = ductParameter.dDuctHeight.ToString();
							}
							else
							{
								cdt.txtWidth.Text = ductParameter.dDuctDiameter.ToString();
							}
							for (int k = 0; k < cdt.cbLevel.Items.Count; k++)
							{
								if (cdt.cbLevel.Items[k].Equals(ductParameter.strLevel))
								{
									cdt.cbLevel.SelectedIndex = k;
									break;
								}
							}
							cdt.ButtonDuiqi(ductParameter.nStyle);
							cdt.getLevelOffset(cdt.cbLevel.Text);
							cdt.tbLevelOffset.Text = Math.Round(ductParameter.dOffset, 0).ToString();
						}
					}
					XYZ xyz = selection.PickPoint("请选择绘制风管的起点...");
					list.Clear();
					list2.Clear();
					XYZ xyz2 = null;
					if (xyz != null)
					{
						for (;;)
						{
							transaction = new Transaction(document, "绘制风管");
							transaction.Start();
							try
							{
								if (cdt.Visible)
								{
									using (DuctCreateJigPolarAxis ductCreateJigPolarAxis = new DuctCreateJigPolarAxis(activeUIDocument, cdt))
									{
										ductCreateJigPolarAxis.StartPoint = xyz;
										ductCreateJigPolarAxis.DrawSize = true;
										Application.DoEvents();
										ductCreateJigPolarAxis.SetPromptState("", false, true);
										xyz2 = ductCreateJigPolarAxis.PickEndPoint(xyz, "请选择绘制风管的终点...");
										ductCreateJigPolarAxis.Dispose();
									}
									if (xyz2 == null)
									{
										break;
									}
									if (xyz2.IsAlmostEqualTo(xyz))
									{
										MessageBox.Show("选择的两点过于接近，无法创建！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
										break;
									}
									DuctWindowStruct data = cdt.GetData(true);
									IList<XYZ> srcPts = new List<XYZ>
									{
										xyz,
										xyz2
									};
									IList<XYZ> list3 = new List<XYZ>
									{
										xyz,
										xyz2
									};
									double num = data.dDuctWidth / 304.8;
									double num2 = xyz.DistanceTo(xyz2);
									num2 = num2 * 304.8 / 1000.0 * data.dBimozu;
									cdt.lbPyPa.Text = "Py(Pa)=" + Math.Round(num2, 2);
									double levelOffset = new FormCreateDuct(uiApp, "绘制横风管", true).getLevelOffset(data.strLevel);
									data.dOffset += levelOffset * 304.8;
									double num3 = data.dOffset / 304.8;
									double num4;
									if (data.dDuctHeight != 0.0)
									{
										num4 = data.dDuctHeight / 2.0 / 304.8;
									}
									else
									{
										num4 = data.dDuctWidth / 2.0 / 304.8;
									}
									if (data.nStyle == 1 || data.nStyle == 2 || data.nStyle == 3)
									{
										num3 -= num4;
									}
									if (data.nStyle == 7 || data.nStyle == 8 || data.nStyle == 9)
									{
										num3 += num4;
									}
									if (data.nStyle == 3 || data.nStyle == 6 || data.nStyle == 9)
									{
										CreateJigLine.OffsetCurve(srcPts, -num / 2.0, out list3, 0.0);
									}
									if (data.nStyle == 1 || data.nStyle == 4 || data.nStyle == 7)
									{
										CreateJigLine.OffsetCurve(srcPts, num / 2.0, out list3, 0.0);
									}
									xyz = list3[0];
									xyz2 = list3[1];
									if ((int)document.ActiveView.ViewType != 3 && (int)document.ActiveView.ViewType != 117)
									{
										xyz = new XYZ(xyz.X, xyz.Y, num3);
										xyz2 = new XYZ(xyz2.X, xyz2.Y, num3);
									}
									else
									{
										if (data.nStyle == 1 || data.nStyle == 2 || data.nStyle == 3)
										{
											xyz = new XYZ(xyz.X, xyz.Y, xyz.Z - num4);
											xyz2 = new XYZ(xyz2.X, xyz2.Y, xyz2.Z - num4);
										}
										if (data.nStyle == 7 || data.nStyle == 8 || data.nStyle == 9)
										{
											xyz = new XYZ(xyz.X, xyz.Y, xyz.Z + num4);
											xyz2 = new XYZ(xyz2.X, xyz2.Y, xyz2.Z + num4);
										}
									}
									List<Curve> list4 = new List<Curve>
									{
										Line.CreateBound(xyz, xyz2)
									};
									list.AddRange(list4);
									Duct duct2 = CreateDuct.CreateDuctStruct(uiApp.ActiveUIDocument.Document, data, cdt.lstOutDuctSytemSet, levelOffset);
									this.CreateParamDuct(uiApp, duct2, cdt.cbSystemType.Text);
									List<Duct> list5 = CreateDuct.CreateListDuct(duct2, list4, data.nHorizontalOffset, levelOffset);
									document.Regenerate();
									if (list2.Count > 0 && list2.Count == 1)
									{
										YJKPiping<Duct> hypiping = new YJKPiping<Duct>(list2[list2.Count - 1]);
										if (YJKRevitTools.IsRiserDuct(list5[0]) && hypiping.BeRotateDuct(list5[0]))
										{
											new YJKPiping<Duct>(list5[0]).Rotate90();
										}
										if (YJKRevitTools.IsRiserDuct(list2[list2.Count - 1]))
										{
											hypiping = new YJKPiping<Duct>(list5[0]);
											if (hypiping.BeRotateDuct(list2[list2.Count - 1]))
											{
												new YJKPiping<Duct>(list5[0]).Rotate90();
											}
										}
									}
									if (CreateDuct.ConnectDuct(document, data, list5, list2))
									{
										List<XYZ> farestTwoPoints = this.GetFarestTwoPoints(new List<XYZ>
										{
											(list2[list2.Count - 1].Location as LocationCurve).Curve.GetEndPoint(0),
											(list2[list2.Count - 1].Location as LocationCurve).Curve.GetEndPoint(1),
											(list5[0].Location as LocationCurve).Curve.GetEndPoint(0),
											(list5[0].Location as LocationCurve).Curve.GetEndPoint(1)
										});
										XYZ xyz3 = farestTwoPoints[0];
										XYZ xyz4 = farestTwoPoints[1];
										document.Delete(list5[0].Id);
										document.Delete(list2[list2.Count - 1].Id);
										list2.RemoveAt(list2.Count - 1);
										list4 = new List<Curve>
										{
											Line.CreateBound(xyz3, xyz4)
										};
										list5 = CreateDuct.CreateListDuct(duct2, list4, 0.0, levelOffset);
									}
									document.Delete(duct2.Id);
									Duct value = list5[0];
									this.LinkDuct(xyz, ref value, document, data);
									list5[0] = value;
									list2.AddRange(list5);
									xyz = xyz2;
									if (data.nStyle == 3 || data.nStyle == 6 || data.nStyle == 9)
									{
										IList<XYZ> list6 = new List<XYZ>
										{
											xyz,
											xyz2
										};
										CreateJigLine.OffsetCurve(list3, num / 2.0, out list6, 0.0);
										xyz = list6[1];
									}
									if (data.nStyle == 1 || data.nStyle == 4 || data.nStyle == 7)
									{
										IList<XYZ> list7 = new List<XYZ>
										{
											xyz,
											xyz2
										};
										CreateJigLine.OffsetCurve(list3, -num / 2.0, out list7, 0.0);
										xyz = list7[1];
									}
									if (data.nStyle == 1 || data.nStyle == 2 || data.nStyle == 3)
									{
										double num5;
										if (data.dDuctHeight != 0.0)
										{
											num5 = data.dDuctHeight / 2.0 / 304.8;
										}
										else
										{
											num5 = data.dDuctWidth / 2.0 / 304.8;
										}
										xyz = new XYZ(xyz.X, xyz.Y, xyz.Z + num5);
									}
									if (data.nStyle == 7 || data.nStyle == 8 || data.nStyle == 9)
									{
										double num5;
										if (data.dDuctHeight != 0.0)
										{
											num5 = data.dDuctHeight / 2.0 / 304.8;
										}
										else
										{
											num5 = data.dDuctWidth / 2.0 / 304.8;
										}
										xyz = new XYZ(xyz.X, xyz.Y, xyz.Z - num5);
									}
									xyz2 = null;
								}
							}
							catch (Autodesk.Revit.Exceptions.OperationCanceledException)
							{
								transaction.RollBack();
								break;
							}
							document.Regenerate();
							transaction.Commit();
						}
						continue;
					}
					cdt.Close();
					result = false;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException)
				{
					if (cdt.blTiqvDuct)
					{
						continue;
					}
					cdt.Close();
					result = true;
				}
				catch (Exception ex)
				{
					if (ex.Message.Contains("Fitting cannot be created between the input connectors because the angle between them is too small or too large."))
					{
						MessageBox.Show("您绘制风管与上一次绘制风管夹角过大或过小！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					else if (ex.Message.Contains("failed to insert elbow."))
					{
						MessageBox.Show("没有可以使用的族配置，请检查Revit的族配置", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					else
					{
						MessageBox.Show(ex.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					this.EndTransation(transaction, false);
					cdt.Close();
					result = true;
				}
				finally
				{
					this.EndTransation(transaction, true);
				}
				break;
			}
			return result;
		}

		private List<XYZ> GetFarestTwoPoints(IList<XYZ> points)
		{
			List<XYZ> list = new List<XYZ>();
			double num = 0.0;
			XYZ item = XYZ.Zero;
			XYZ item2 = XYZ.Zero;
			for (int i = 0; i < points.Count - 1; i++)
			{
				for (int j = i + 1; j < points.Count; j++)
				{
					if (points[i].DistanceTo(points[j]) > num)
					{
						num = points[i].DistanceTo(points[j]);
						item = points[i];
						item2 = points[j];
					}
				}
			}
			list.Add(item);
			list.Add(item2);
			return list;
		}

		private bool LinkDuct(XYZ point, ref Duct duct, Autodesk.Revit.DB.Document doc, DuctWindowStruct paraW)
		{
			List<Duct> pickPipe = this.GetPickPipe(point, 0.032808398950131233, doc);
			SubTransaction subTransaction = new SubTransaction(doc);
			subTransaction.Start();
			bool result = true;
			try
			{
				result = this.ConnectDucts(doc, pickPipe, ref duct, point, paraW);
				subTransaction.Commit();
			}
			catch (Exception)
			{
				subTransaction.RollBack();
			}
			List<Element> elementByCollision = this.GetElementByCollision(duct, BuiltInCategory.OST_DuctCurves, doc);
			this.CrossConnDucts(elementByCollision, ref duct, point);
			return result;
		}

		public bool CrossConnDucts(List<Element> pipes, ref Duct pipe, XYZ point)
		{
			try
			{
				HYDuctConnect hyductConnect = new HYDuctConnect();
				SortedDictionary<double, Element> sortedDictionary = new SortedDictionary<double, Element>();
				bool result = false;
				foreach (Element element in pipes)
				{
					if (this.FilterDuctType(element as Duct, pipe))
					{
						Line line = (element.Location as LocationCurve).Curve as Line;
						double distance = new YJKLine(line.GetEndPoint(0), line.GetEndPoint(1)).GetDistance(point);
						sortedDictionary.Add(distance, element);
					}
				}
				foreach (KeyValuePair<double, Element> keyValuePair in sortedDictionary)
				{
					Line line2 = (pipe.Location as LocationCurve).Curve as Line;
					YJKLine hyline = new YJKLine(line2.GetEndPoint(0), line2.GetEndPoint(1));
					Line line3 = (keyValuePair.Value.Location as LocationCurve).Curve as Line;
					if (hyline.IsVertical(line3))
					{
						IList<Duct> list = new List<Duct>();
						list.Add(pipe);
						list.Add(pipe);
						list.Add(keyValuePair.Value as Duct);
						list.Add(keyValuePair.Value as Duct);
						result = hyductConnect.NewCrossFitting(ref list, null);
						double num = 0.0;
						foreach (Duct duct in list)
						{
							XYZ end = new XYZ(point.X, point.Y, point.Z + 10.0);
							YJKLine hyline2 = new YJKLine(point, end);
							Line line4 = (duct.Location as LocationCurve).Curve as Line;
							YJKLine hyline3 = new YJKLine(line4.GetEndPoint(0), line4.GetEndPoint(1));
							if (Math.Round(hyline2.GetDPLineDistance(hyline3.Line), 3, MidpointRounding.AwayFromZero) == 0.0)
							{
								double dplineDistance = this.GetDPLineDistance2(hyline3.Line, hyline2);
								if (dplineDistance > num)
								{
									num = dplineDistance;
									pipe = duct;
								}
							}
						}
					}
				}
				return result;
			}
			catch (Exception)
			{
			}
			return true;
		}

		public bool FilterDuctType(Duct pipe1, Duct pipe2)
		{
			return pipe1.GetParameter("系统类型").AsValueString() == pipe2.GetParameter("系统类型").AsValueString();
		}

		public List<Element> GetElementByCollision(Element tagElement, BuiltInCategory needElement, Autodesk.Revit.DB.Document doc)
		{
			List<Element> list = new List<Element>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			ElementIntersectsElementFilter elementIntersectsElementFilter = new ElementIntersectsElementFilter(tagElement);
			filteredElementCollector.WherePasses(elementIntersectsElementFilter);
			foreach (Element element in filteredElementCollector)
			{
                if (element.Category.Id.IntegerValue == (int)needElement)
				{
					list.Add(element);
				}
			}
			return list;
		}

		private bool ConnectDucts(Autodesk.Revit.DB.Document doc, List<Duct> lst, ref Duct duct, XYZ point, DuctWindowStruct paraW)
		{
			if (lst.Count != 2)
			{
				return false;
			}
			IList<Duct> list = new List<Duct>();
			Duct duct2 = (lst[0].Id == duct.Id) ? lst[1] : lst[0];
			new RefrigerantPipeCreate();
			if (!this.FilterPipeType(duct2, duct))
			{
				return false;
			}
			list.Add(duct2);
			list.Add(duct);
			YJKPiping<Duct> hypiping = new YJKPiping<Duct>(duct2);
			int num = this.CheckPipePosition(duct2, duct);
			HYDuctConnect hyductConnect = new HYDuctConnect();
			double offSet = hypiping.GetOffSet();
			switch (num)
			{
			case 10:
				if (CreateDuct.CreateDuctZhi(paraW, new List<Duct>
				{
					duct2,
					duct
				}))
				{
					List<XYZ> farestTwoPoints = this.GetFarestTwoPoints(new List<XYZ>
					{
						(duct2.Location as LocationCurve).Curve.GetEndPoint(0),
						(duct2.Location as LocationCurve).Curve.GetEndPoint(1),
						(duct.Location as LocationCurve).Curve.GetEndPoint(0),
						(duct.Location as LocationCurve).Curve.GetEndPoint(1)
					});
					XYZ xyz = farestTwoPoints[0];
					XYZ xyz2 = farestTwoPoints[1];
					List<Curve> lstCurve = new List<Curve>
					{
						Line.CreateBound(xyz, xyz2)
					};
					List<Duct> list2 = CreateDuct.CreateListDuct(duct, lstCurve, paraW.nHorizontalOffset, offSet);
					doc.Delete(duct2.Id);
					doc.Delete(duct.Id);
					duct = list2[0];
					return true;
				}
				hyductConnect.NewTransitionFitting(new List<Duct>
				{
					duct2,
					duct
				});
				return true;
			case 11:
				return true;
			case 12:
				break;
			case 13:
				goto IL_1EB;
			default:
				if (num != 22)
				{
					if (num != 23)
					{
						return true;
					}
					goto IL_1EB;
				}
				break;
			}
			hyductConnect.NewElbowFitting(new List<Duct>
			{
				duct2,
				duct
			});
			return true;
			IL_1EB:
			hyductConnect.NewTeeFitting(new List<Duct>
			{
				duct2,
				duct2,
				duct
			});
			return true;
		}

		public bool IsLineOnLine(YJKLine hyLine1, YJKLine hyLine2, double deviation)
		{
			hyLine1.MakeUnBound();
			return hyLine1.GetDistance(hyLine2.StartPoint) < deviation && hyLine1.GetDistance(hyLine2.EndPoint) < deviation;
		}

		public int CheckPipePosition(Duct pipe1, Duct pipe2)
		{
			int result = 0;
			Parameter parameter = pipe1.GetParameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM);
			Parameter parameter2 = pipe1.GetParameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
			double num = 0.0;
			if (parameter != null)
			{
				num = parameter.AsDouble();
			}
			if (parameter2 != null)
			{
				num = parameter2.AsDouble();
			}
			YJKPiping<Duct> hypiping = new YJKPiping<Duct>(pipe1);
			YJKPiping<Duct> hypiping2 = new YJKPiping<Duct>(pipe2);
			Curve curve = (pipe1.Location as LocationCurve).Curve;
			Line otherLine = (pipe2.Location as LocationCurve).Curve as Line;
			YJKLine hyline = new YJKLine(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
			YJKLine hyline2 = new YJKLine(hypiping2.StartConnector.Origin, hypiping2.EndConnector.Origin);
			if (this.IsLineOnLine(hyline, hyline2, 0.03))
			{
				result = 10;
			}
			else if (hyline.GetDPLineDistance(otherLine) > num * 3.0 || (hyline.IsXYParallel(otherLine) && hyline.GetDistance(hyline2.StartPoint) > num * 3.0))
			{
				XYZ origin = hypiping.StartConnector.Origin;
				XYZ origin2 = hypiping.EndConnector.Origin;
				XYZ origin3 = hypiping2.StartConnector.Origin;
				XYZ origin4 = hypiping2.EndConnector.Origin;
				XYZ xyz = new XYZ(origin.X, origin.Y, 0.0);
				XYZ xyz2 = new XYZ(origin2.X, origin2.Y, 0.0);
				XYZ xyz3 = new XYZ(origin3.X, origin3.Y, 0.0);
				XYZ xyz4 = new XYZ(origin4.X, origin4.Y, 0.0);
				if (xyz.DistanceTo(xyz3) < num || xyz.DistanceTo(xyz4) < num || xyz2.DistanceTo(xyz3) < num || xyz2.DistanceTo(xyz4) < num)
				{
					result = 22;
				}
				else
				{
					result = 23;
				}
			}
			else if (hyline.IntersectionPoint(otherLine, 0.03) != null)
			{
				if (hypiping.StartConnector.Origin.DistanceTo(hypiping2.StartConnector.Origin) < num || hypiping.StartConnector.Origin.DistanceTo(hypiping2.EndConnector.Origin) < num || hypiping.EndConnector.Origin.DistanceTo(hypiping2.StartConnector.Origin) < num || hypiping.EndConnector.Origin.DistanceTo(hypiping2.EndConnector.Origin) < num)
				{
					result = 12;
				}
				else
				{
					result = 13;
				}
			}
			return result;
		}

		public bool FilterPipeType(Duct pipe1, Duct pipe2)
		{
			return pipe1.GetParameter("系统类型").AsValueString() == pipe2.GetParameter("系统类型").AsValueString();
		}

		public List<Duct> GetPickPipe(XYZ point, double size, Autodesk.Revit.DB.Document doc)
		{
			XYZ point2 = new XYZ(point.X + size, point.Y + size, point.Z);
			XYZ point3 = new XYZ(point.X - size, point.Y - size, point.Z);
			List<Duct> list = new List<Duct>();
			try
			{
				BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(RevitAPIUIOperate.CreatOutLine(RevitAPIUIOperate.GetViewRange2(doc.ActiveView, false), point2, point3));
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
				filteredElementCollector.OfClass(typeof(Duct)).OfCategory(BuiltInCategory.OST_DuctCurves).WherePasses(boundingBoxIntersectsFilter);
				XYZ end = new XYZ(point.X, point.Y, point.Z + 10.0);
				YJKLine hyline = new YJKLine(point, end);
				foreach (Element element in filteredElementCollector)
				{
					Duct duct = (Duct)element;
					YJKPiping<Duct> hypiping = new YJKPiping<Duct>(duct);
					YJKLine hyline2 = new YJKLine(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
					if (Math.Abs(hypiping.StartConnector.Origin.X - hypiping.EndConnector.Origin.X) < 1.0 && Math.Abs(hypiping.StartConnector.Origin.Y - hypiping.EndConnector.Origin.Y) < 1.0 && new XYZ(hypiping.StartConnector.Origin.X, hypiping.StartConnector.Origin.Y, point.Z).DistanceTo(point) <= duct.GetParameter("宽度").AsDouble() / 2.0)
					{
						list.Add(duct);
					}
					else if (this.GetDPLineDistance2(hyline2.Line, hyline) != -1.0 && this.GetDPLineDistance2(hyline2.Line, hyline) <= hypiping.GetWeightOrDiameter() / 2.0)
					{
						list.Add(duct);
					}
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
			return list;
		}

		private double GetDPLineDistance2(Line otherLine, YJKLine hyline1)
		{
			double num = -1.0;
			if (hyline1.Line == null)
			{
				return num;
			}
			if (!hyline1.IsParallel(otherLine))
			{
				XYZ hyendPoint = otherLine.GetEndPoint(0);
				XYZ hyendPoint2 = otherLine.GetEndPoint(1);
				XYZ xyz = YJKRevitTools.GetDLineP(hyline1.StartPoint, hyline1.EndPoint, hyendPoint, hyendPoint2);
				if (!new YJKLine(hyendPoint, hyendPoint2).IsPointOnLine(xyz))
				{
					xyz = ((xyz.DistanceTo(hyendPoint) < xyz.DistanceTo(hyendPoint2)) ? hyendPoint : hyendPoint2);
				}
				XYZ dlineP = YJKRevitTools.GetDLineP(hyendPoint, hyendPoint2, hyline1.StartPoint, hyline1.EndPoint);
				num = xyz.DistanceTo(dlineP);
				num = Math.Round(num, 3, MidpointRounding.AwayFromZero);
			}
			return num;
		}

		private double[] GetViewRange(Autodesk.Revit.DB.View view)
		{
			if (!(view is ViewPlan))
			{
				return null;
			}
			Document document = view.Document;
			double[] array = new double[2];
			PlanViewRange viewRange = (view as ViewPlan).GetViewRange();
			ElementId levelId = viewRange.GetLevelId(0);
			double num = 30.0;
            ElementId levelId2 = viewRange.GetLevelId((Autodesk.Revit.DB.PlanViewPlane)1);
			if (levelId2 != null && document.GetElementById(levelId) != null && document.GetElementById(levelId2) is Level)
			{
                num = (document.GetElementById(levelId2) as Level).Elevation + viewRange.GetOffset((Autodesk.Revit.DB.PlanViewPlane)1);
			}
			double elevation = (document.GetElementById(levelId) as Level).Elevation;
			array[1] = elevation + num;
            ElementId levelId3 = viewRange.GetLevelId((Autodesk.Revit.DB.PlanViewPlane)2);
			if (levelId3.IntegerValue <= 0)
			{
				array[0] = elevation;
			}
			else
			{
                double offset = viewRange.GetOffset((Autodesk.Revit.DB.PlanViewPlane)2);
				double elevation2 = (document.GetElementById(levelId3) as Level).Elevation;
				array[0] = elevation2 + offset;
			}
			return array;
		}

		private static bool OffsetCurve(IList<XYZ> srcPts, double dOffSet, out IList<XYZ> offsetPoints, double dZOffset = 0.0)
		{
			offsetPoints = new List<XYZ>();
			IList<XYZ> list = new List<XYZ>();
			for (int i = 0; i < srcPts.Count; i++)
			{
				if (i == 0)
				{
					list.Add(srcPts[i]);
				}
				else if (srcPts[i].DistanceTo(list.Last<XYZ>()) > 0.001)
				{
					list.Add(srcPts[i]);
				}
			}
			if (list.Count < 2)
			{
				return false;
			}
			XYZ xyz = new XYZ(0.0, 0.0, 1.0) * dZOffset;
			if (list.Count == 2)
			{
				XYZ xyz2 = list[1] - list[0];
				xyz2 = new XYZ(-xyz2.Y, xyz2.X, 0.0);
				xyz2 = xyz2.Normalize();
				offsetPoints.Add(list[0] - dOffSet * xyz2 + xyz);
				offsetPoints.Add(list[1] - dOffSet * xyz2 + xyz);
				return true;
			}
			for (int j = 1; j < list.Count - 1; j++)
			{
				XYZ xyz3 = list[j - 1];
				XYZ xyz4 = list[j];
				XYZ xyz5 = list[j + 1];
				XYZ xyz6 = xyz4 - xyz3;
				xyz6 = new XYZ(xyz6.X, xyz6.Y, 0.0);
				xyz6 = xyz6.Normalize();
				XYZ xyz7 = new XYZ(-xyz6.Y, xyz6.X, 0.0);
				XYZ xyz8 = xyz5 - xyz4;
				xyz8 = new XYZ(xyz8.X, xyz8.Y, 0.0);
				xyz8 = xyz8.Normalize();
				XYZ xyz9 = new XYZ(-xyz8.Y, xyz8.X, 0.0);
				if (j == 1)
				{
					offsetPoints.Add(xyz3 - dOffSet * xyz7 + xyz);
				}
				if (xyz7.IsAlmostEqualTo(xyz9))
				{
					offsetPoints.Add(xyz4 - dOffSet * xyz7 + xyz);
				}
				else
				{
					XYZ xyz10 = xyz7 + xyz9;
					xyz10 = xyz10.Normalize();
					double d = xyz7.AngleTo(xyz10);
					offsetPoints.Add(xyz4 - dOffSet * xyz10 / Math.Cos(d) + xyz);
				}
				if (j == list.Count - 2)
				{
					offsetPoints.Add(xyz5 - dOffSet * xyz9 + xyz);
				}
			}
			return true;
		}

		public bool CreateDuctLineV(UIApplication uiApp, FormCreateDuct cdt)
		{
			List<Curve> list = new List<Curve>();
			List<Duct> list2 = new List<Duct>();
			Selection selection = uiApp.ActiveUIDocument.Selection;
			UIDocument activeUIDocument = uiApp.ActiveUIDocument;
			Document document = activeUIDocument.Document;
			Transaction transaction = null;
			int nType = 0;
			bool result;
			for (;;)
			{
				try
				{
					if (cdt.blTiqvDuct)
					{
						cdt.blTiqvDuct = false;
						ISelectionFilter selectionFilter = new DuctFilter();
						Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "选择一根风管……");
						Duct duct = document.GetElement(reference) as Duct;
						if (duct != null)
						{
							DuctWindowStruct ductParameter = GetDuctPara.GetDuctParameter(uiApp.ActiveUIDocument.Document, duct);
							string text = cdt.cbStartLevel.Text;
							string text2 = cdt.cbEndLevel.Text;
							cdt.getLevelOffset(text);
							cdt.getLevelOffset(text2);
							if (cdt.rbjdLevel.Checked)
							{
								cdt.cbStartOffset.Text = Math.Round(ductParameter.dSOffset, 0).ToString();
								cdt.cbEndOffset.Text = Math.Round(ductParameter.dEOffset, 0).ToString();
							}
							else
							{
								cdt.cbStartLevel.Text = ductParameter.strLevel;
								cdt.cbEndLevel.Text = ductParameter.strLevel;
								cdt.cbStartOffset.Text = Math.Round(ductParameter.dSOffset, 0).ToString();
								cdt.cbEndOffset.Text = Math.Round(ductParameter.dEOffset, 0).ToString();
							}
							for (int i = 0; i < cdt.cbSystemType.Items.Count; i++)
							{
								if (cdt.cbSystemType.Items[i].Equals(ductParameter.strSystemType))
								{
									cdt.cbSystemType.SelectedIndex = i;
									break;
								}
							}
							for (int j = 0; j < cdt.cbDuctType.Items.Count; j++)
							{
								if (cdt.cbDuctType.Items[j].ToString().Contains(ductParameter.strDuctType) && ((cdt.cbDuctType.Items[j].ToString().Contains("椭圆") && ductParameter.strDuctType.Contains("椭圆")) || (!cdt.cbDuctType.Items[j].ToString().Contains("椭圆") && !ductParameter.strDuctType.Contains("椭圆"))))
								{
									cdt.cbDuctType.SelectedIndex = j;
									break;
								}
							}
							cdt.tbFlow.Text = ductParameter.dDuctFlow.ToString();
							if (ductParameter.dDuctDiameter == 0.0)
							{
								cdt.txtWidth.Text = ductParameter.dDuctWidth.ToString();
								cdt.txtHeight.Text = ductParameter.dDuctHeight.ToString();
							}
							else
							{
								cdt.txtWidth.Text = ductParameter.dDuctDiameter.ToString();
							}
							for (int k = 0; k < cdt.cbLevel.Items.Count; k++)
							{
								if (cdt.cbLevel.Items[k].Equals(ductParameter.strLevel))
								{
									cdt.cbLevel.SelectedIndex = k;
									break;
								}
							}
						}
					}
					XYZ xyz = XYZ.Zero;
					if (cdt.Visible)
					{
						using (DuctVJigPolarAxis ductVJigPolarAxis = new DuctVJigPolarAxis(activeUIDocument, cdt))
						{
							xyz = ductVJigPolarAxis.PickStartPoint("请确定布置点：");
							nType = ductVJigPolarAxis.nTypeStation;
							Application.DoEvents();
							ductVJigPolarAxis.Dispose();
						}
					}
					list.Clear();
					list2.Clear();
					if (xyz != null || !cdt.blTiqvDuct)
					{
						if (xyz == null && !cdt.blTiqvDuct)
						{
							cdt.Close();
							result = false;
							break;
						}
						transaction = new Transaction(document, "绘制风管");
						transaction.Start();
						try
						{
							if (cdt.Visible)
							{
								DuctWindowStruct data = cdt.GetData(true);
								double num = Math.Abs(data.dEOffset - data.dSOffset);
								num = num * 304.8 / 1000.0 * data.dBimozu;
								cdt.lbPyPa.Text = "Py(Pa)=" + Math.Round(num, 2);
								Duct duct2 = CreateDuct.CreateDuctStruct(uiApp.ActiveUIDocument.Document, data, cdt.lstOutDuctSytemSet, 0.0);
								xyz = this.GetStation(nType, xyz, data.dDuctWidth / 304.8, data.dDuctHeight / 304.8);
								double x = xyz.X;
								double y = xyz.Y;
								Level level = cdt.Get_Level(document, data.strLevel);
								if (cdt.rbjdLevel.Checked)
								{
									level = document.ActiveView.GenLevel;
								}
								MechanicalSystemType ductSystemType = this.Get_DuctSystemType(document, data.strSystemType);
								this.Draw(x, y, data.dSOffset, data.dEOffset, document, duct2, data.dDuctWidth, data.dDuctHeight, ductSystemType, level);
								document.Delete(duct2.Id);
							}
						}
						catch
						{
							transaction.RollBack();
							continue;
						}
						document.Regenerate();
						transaction.Commit();
					}
					continue;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException)
				{
					if (cdt.blTiqvDuct)
					{
						continue;
					}
					cdt.Close();
					result = true;
				}
				catch (Exception ex)
				{
					if (ex.Message.Contains("Fitting cannot be created between the input connectors because the angle between them is too small or too large."))
					{
						MessageBox.Show("您绘制风管与上一次绘制风管夹角过大或过小！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					else if (ex.Message.Contains("failed to insert elbow."))
					{
						MessageBox.Show("没有可以使用的族配置，请检查Revit的族配置", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					else
					{
						MessageBox.Show(ex.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					this.EndTransation(transaction, false);
					cdt.Close();
					result = true;
				}
				finally
				{
					this.EndTransation(transaction, true);
				}
				break;
			}
			return result;
		}

		private XYZ GetStation(int nType, XYZ point, double dWidth, double dHeight)
		{
			XYZ result = point;
			if (dHeight == 0.0)
			{
				return point;
			}
			if (nType == 1)
			{
				result = new XYZ(point.X - dWidth / 2.0, point.Y + dHeight / 2.0, point.Z);
			}
			else if (nType == 2)
			{
				result = new XYZ(point.X - dWidth / 2.0, point.Y - dHeight / 2.0, point.Z);
			}
			else if (nType == 3)
			{
				result = new XYZ(point.X + dWidth / 2.0, point.Y - dHeight / 2.0, point.Z);
			}
			else if (nType == 4)
			{
				result = new XYZ(point.X + dWidth / 2.0, point.Y + dHeight / 2.0, point.Z);
			}
			return result;
		}

		public MechanicalSystemType Get_DuctSystemType(Autodesk.Revit.DB.Document document, string ductSystemTypeName)
		{
			return YJKRevitTools.GetSameNameElement(YJKElementFilter.GetElementByClass(typeof(MechanicalSystemType), document), ductSystemTypeName) as MechanicalSystemType;
		}

		public void Draw(double x, double y, double zStart, double zEnd, Autodesk.Revit.DB.Document document, Duct ductOld, double width, double height, MechanicalSystemType ductSystemType, Level level)
		{
			double projectElevation = level.ProjectElevation;
			XYZ startXYZ = new XYZ(x, y, zStart);
			XYZ endXYZ = new XYZ(x, y, zEnd);
			Duct duct = this.NewDuct(ductOld, startXYZ, endXYZ);
			if (duct != null)
			{
				if (height == 0.0)
				{
					duct.GetParameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).Set(width / 304.8);
				}
				else
				{
					Parameter parameter = duct.GetParameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
					Parameter parameter2 = duct.GetParameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
					parameter.Set(width / 304.8);
					parameter2.Set(height / 304.8);
				}
				duct.GetParameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM).Set(ductSystemType.Id);
				duct.GetParameter(BuiltInParameter.RBS_START_LEVEL_PARAM).Set(level.Id);
				duct.LevelOffset = zStart;
			}
		}

		public Duct NewDuct(Duct sourceDuct, XYZ startXYZ, XYZ endXYZ)
		{
			Duct duct = null;
			if (sourceDuct == null || startXYZ == null || endXYZ == null)
			{
				return null;
			}
			Document document = sourceDuct.Document;
			YJKDocument hydocument = new YJKDocument(document);
			foreach (ElementId elementId in ElementTransformUtils.CopyElement(document, sourceDuct.Id, new XYZ(0.0, 0.0, 0.0)))
			{
				duct = (hydocument.GetElement(elementId) as Duct);
			}
			document.Regenerate();
			if (duct != null)
			{
				Line line = new YJKLine(startXYZ, endXYZ).Line;
				(duct.Location as LocationCurve).Curve = line;
			}
			document.Regenerate();
			ElementTransformUtils.MoveElement(document, duct.Id, new XYZ(0.001, 0.001, 0.001));
			ElementTransformUtils.MoveElement(document, duct.Id, -1.0 * new XYZ(0.001, 0.001, 0.001));
			return duct;
		}

		private void EndTransation(Transaction tran, bool beSure)
		{
			if (tran != null)
			{
				TransactionStatus status = tran.GetStatus();
				if ((int)status == 1)
				{
					if (beSure)
					{
						tran.Commit();
						return;
					}
					tran.RollBack();
					return;
				}
				else if ((int)status == 5)
				{
					tran.RollBack();
				}
			}
		}

		private void CreateParamDuct(UIApplication uiApp, Element element, string strSystemType)
		{
			List<string> list = new List<string>();
			list.Add("压力等级");
			list.Add("默认材质");
			SqlLiteHelp.SqlLiteDatabase(Path.Combine(Product.DataLocation, "HYBIMSPACE.db3"));
			DuctSytemSet systemTypePara = SqlLiteHelp.GetSystemTypePara(strSystemType);
            ParameterType value = (ParameterType)1;
			foreach (string text in list)
			{
				if (element.GetParameter(text) == null)
				{
					BuiltInCategory integerValue = (Autodesk.Revit.DB.BuiltInCategory)(element.Category.Id.IntegerValue);
					Dictionary<string, ParameterType> dictionary = new Dictionary<string, ParameterType>();
					dictionary.Add(text, value);
					ShareParameterOperator.InsertSharedParameter(element.Document, integerValue, "风管信息", dictionary, true);
				}
				if (text.Equals("压力等级"))
				{
					this.SetParameterValue(element, text, systemTypePara.strPresslevel);
				}
				else
				{
					this.SetParameterValue(element, text, systemTypePara.strMateria);
				}
			}
		}

		private bool SetParameterValue(Element element, string name, object value)
		{
			if (element == null || string.IsNullOrEmpty(name) || value == null)
			{
				return false;
			}
			bool result;
			try
			{
				Parameter parameter = element.GetParameter(name);
				if (parameter == null)
				{
					result = false;
				}
				else
				{
					bool flag;
                    switch ((int)parameter.StorageType)
					{
					case 1:
						flag = parameter.Set(Convert.ToInt32(value));
						goto IL_BC;
					case 2:
					{
						double num = UnitConvert.CovertToAPI(Convert.ToDouble(value), parameter.DisplayUnitType);
						flag = parameter.Set(num);
						goto IL_BC;
					}
					case 4:
					{
						ElementId elementId;
						if (value.GetType() == typeof(ElementId))
						{
							elementId = (value as ElementId);
						}
						else
						{
							elementId = new ElementId(Convert.ToInt32(value));
						}
						flag = parameter.Set(elementId);
						goto IL_BC;
					}
					}
					flag = parameter.Set(value.ToString());
					IL_BC:
					result = flag;
				}
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}
	}
}
